/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package transervfx.Vista;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.Property;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Duration;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import recursos.img.pathRecusosIMG;

import transervfx.Dato.Entidad.Domicilio;
import transervfx.Dato.Entidad.Externa;
import transervfx.Dato.Entidad.Localidad;
import transervfx.Dato.Entidad.Pais;
import transervfx.Dato.Entidad.Provincia;
import transervfx.Dato.Validacion.ValidacionesNivelBD;
import transervfx.Dato.Validacion.ValidacionesNivelLogico;
import transervfx.Logica.GestorAgencia;
import transervfx.Logica.GestorPais;
import transervfx.Vista.XML.pathRecusosFXML;
import utilidades.autocompletar.TextBoxAutoCompletar;
import utilidades.number.IntegerTextField;

/**
 * FXML Controller class
 *
 * @author oscar
 */
public class CrearAgenciaExterna extends VentanaModal {

   
    private Externa agenciaView = new Externa();
    private BeanPathAdapter<Externa> agenciaViewPA=  new BeanPathAdapter<>(agenciaView);
    private Domicilio domicilioAux = new Domicilio();
    private BeanPathAdapter<Domicilio> domicilioAuxPA=new BeanPathAdapter<>(domicilioAux);
   
    //AGENCIA
    @FXML
    private TextField nombre;
    @FXML
    private TextField cuit;
    @FXML
    private TextField email;
    @FXML
    private ComboBox<String> condicionFrenteIVA;
    @FXML
    private TextField telFijo1;
    @FXML
    private TextField telFijo2;
    @FXML
    private TextField telCelular1;
    @FXML
    private TextField telCelular2;
    //DOMICILIO
    @FXML
    private TextField calle;
    @FXML
    private IntegerTextField numero;
    @FXML
    private TextField departamento;
    @FXML
    private IntegerTextField piso;
    @FXML
    private TextBoxAutoCompletar<Localidad> localidad;
    @FXML
    private ComboBox<Provincia> provincia;
    @FXML
    private ComboBox<Pais> pais;
    //covertura existente
    @FXML
    private ComboBox<Pais> paisesZona;
    @FXML
    private ComboBox<Provincia> provinciaZona;
    @FXML
    private ListView<Localidad> localidadesZona;
    @FXML
    private CheckBox seleccionarTodasLocalidades;
    //covertura de la agencia
    @FXML
    private TableView<Localidad> TablaCoberturaActual;
    final ObservableList<Localidad> dataSourceTablaLocalidadCobertura = FXCollections.observableArrayList();
    @FXML
    private TableColumn columPais;
    final ObservableList<Pais> dataSourcePais = FXCollections.observableArrayList();
    @FXML
    private TableColumn columProvincia;
    final ObservableList<Provincia> dataSourceProvincia = FXCollections.observableArrayList();
    @FXML
    private TableColumn columLocalidad;
    final ObservableList<Localidad> dataSourceLocalidad = FXCollections.observableArrayList();
    @FXML
    private Button agregarZona;
    @FXML
    private Button eliminarZona;
    ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
    Validator validator = validatorFactory.getValidator();
    
    

    
     public CrearAgenciaExterna(Stage ventanaPadre,String titulo,int x, int y) {
        super( ventanaPadre, titulo, x,  y);
        init();
    }
     
    public void init() {
        // TODO
        try {

            this.setTablaCoberturaLocalidades();


            //linqueo interfaz con bean
            this.bindingInterfazConBean(this.agenciaView, this.domicilioAux);
            
            

            this.cargarPaicesProvinciasLocalidades();


            this.agregarEscuchadorAgencia();
            this.agregarEscuchadorDomicilio();
           

            
            


        } catch (NoSuchMethodException ex) {
            Logger.getLogger(CrearAgenciaExterna.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
      private ChangeListener<Boolean> escuchadorFocoAgencia=new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                //si tiene el foco
                Control control=(Control) ((ReadOnlyBooleanProperty)observable).getBean();
                if(!newValue.booleanValue()) 
                {  
                   
                 //   System.out.println("Foco viejo"+((ReadOnlyBooleanProperty)observable).getBean());
                    validarAgencia(control);

                }
            }
        };
       
        private ChangeListener<Boolean> escuchadorFocoDomicilio=new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                //si tiene el foco
                Control control=(Control) ((ReadOnlyBooleanProperty)observable).getBean();
                if(!newValue.booleanValue())
                {  
                   
                 //   System.out.println("Foco viejo"+((ReadOnlyBooleanProperty)observable).getBean());
                    validarDomicilio(control);

                }
            }
        };

    public void salirEvent(ActionEvent event) {
        System.out.println(((Button) event.getSource()).getText());
        //root.getScene().getWindow().hide();
        this.close();
    }

    public void guardarEvent() throws NoSuchMethodException, IOException {


      
        if ( validarDomicilio(this.localidad.getTextField()) & validarDomicilio(this.calle) & validarDomicilio(this.numero) & validarDomicilio(this.departamento ) & validarDomicilio(this.piso) & validarAgencia(this.nombre) & validarAgencia(this.cuit) & validarAgencia(this.email) & validarAgencia(this.condicionFrenteIVA) & validarAgencia(this.telCelular1) & validarAgencia(this.telCelular2) & validarAgencia(this.telFijo1) & validarAgencia(this.telFijo2)) {

            this.agenciaView.setDomicilio(this.domicilioAux);
            this.agenciaView.getZonasCobertura().addAll(this.dataSourceTablaLocalidadCobertura);
            GestorAgencia.getInstance().guardarAgencia(this.agenciaView);
            System.out.println("agencia guardada");

            ((ABMAgenciaExterna)ventanaPadre).actualizarTabla(agenciaView);
            this.close();

          
        }
        else{
            System.out.println("es invalido");
        }
    }
    
     

    //el id de la propiedad es para cada input (EJ: textfiel)
    //y cada input debe estar con el mismo nombre q la entidad que se vincula.
    //retorna true si no posee errores
    private boolean validarDomicilio(Control control) {
          String text="";
          String nombreDelInput=control.getId();
          
          if(control==this.localidad.getTextField()){
              this.domicilioAux.setLocalidad(this.localidad.getValue());
          }
        
         
        
                control.getTooltip().setText(text);
                
                Set<ConstraintViolation<Domicilio>> errorsProperty = validator.validateProperty(this.domicilioAux, nombreDelInput,ValidacionesNivelLogico.class);
                //retorna verdadero si no hay errores
                if(errorsProperty.isEmpty()){
       
                     control.getTooltip().setGraphic(crearImagenSuccess());
                     control.getTooltip().setText("SIN ERRORES");
                      control.setStyle("-fx-border-color: null;");
                      //System.out.println(control.getStyleClass());
                    return true;
                }
                else{
                      control.getTooltip().setGraphic(crearImagenError());
                      text="ERRORES: ";
                      control.setStyle("-fx-border-color: RED;");
                     // control.getStyleClass().clear();
                     // control.getStyleClass().add("controlError");
                for (ConstraintViolation<Domicilio> domiError : errorsProperty) {
                      text=text+"\n"+domiError.getMessage();
                 }
                
                  control.getTooltip().setText(text);
              
                 //si no tiene errores retorna verdadero
                }
       
          
          return false;
    }
    
    
   
    
     private boolean validarAgencia(Control control) {
          String text="";
          String nombreDelInput=control.getId();
        
         
        
                control.getTooltip().setText(text);
                
                Set<ConstraintViolation<Externa>> errorsProperty = validator.validateProperty(this.agenciaView, nombreDelInput,ValidacionesNivelLogico.class);
                //retorna verdadero si no hay errores
                if(errorsProperty.isEmpty()){
       
                     control.getTooltip().setGraphic(crearImagenSuccess());
                     control.getTooltip().setText("SIN ERRORES");
                      control.setStyle("-fx-border-color: null;");
                      //System.out.println(control.getStyleClass());
                    return true;
                }
                else{
                      control.getTooltip().setGraphic(crearImagenError());
                      text="ERRORES: ";
                      control.setStyle("-fx-border-color: RED;");
                     // control.getStyleClass().clear();
                     // control.getStyleClass().add("controlError");
                for (ConstraintViolation<Externa> agenError : errorsProperty) {
                      text=text+"\n"+agenError.getMessage();
                 }
                
                  control.getTooltip().setText(text);
              
                 //si no tiene errores retorna verdadero
                }
       
          
          return false;

    }
    
    
   
   
  


    private void bindingInterfazConBean(Externa agenciaView, Domicilio domicilio) throws NoSuchMethodException {
        //bind agencia externa
       
           agenciaViewPA.bindBidirectional("condicionFrenteIVA", condicionFrenteIVA.valueProperty(),String.class);   
           agenciaViewPA.bindBidirectional("cuit", cuit.textProperty());
           agenciaViewPA.bindBidirectional("email", email.textProperty());
           agenciaViewPA.bindBidirectional("nombre", nombre.textProperty());
           agenciaViewPA.bindBidirectional("telCelular1", telCelular1.textProperty());
           agenciaViewPA.bindBidirectional("telCelular2", telCelular2.textProperty());
           agenciaViewPA.bindBidirectional("telFijo1", telFijo1.textProperty());
           agenciaViewPA.bindBidirectional("telFijo2", telFijo2.textProperty(),String.class);
        
        
        //domicilio
            
          domicilioAuxPA.bindBidirectional("calle", calle.textProperty());
           domicilioAuxPA.bindBidirectional("numero", numero.numberProperty());
           domicilioAuxPA.bindBidirectional("departamento", departamento.textProperty());
           domicilioAuxPA.bindBidirectional("piso", piso.numberProperty());

    }

     

 

    private void cargarPaicesProvinciasLocalidades() {


        localidad.setData(dataSourceLocalidad);
        provincia.setItems(dataSourceProvincia);
        dataSourcePais.addAll(GestorPais.getInstance().paises());
        pais.setItems(dataSourcePais);


        provincia.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Provincia>() {
            @Override
            public void changed(ObservableValue<? extends Provincia> selected, Provincia oldValue, Provincia newValue) {
                if (newValue != null) {
                    localidad.setText("");
                    localidad.setData(GestorPais.getInstance().localidades(newValue));

                    //dataSourceProvincia.clear();
                    //dataSourceProvincia.addAll( GestorPais.getInstance().provincias(newValue));
                }
            }
        });


        pais.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Pais>() {
            @Override
            public void changed(ObservableValue<? extends Pais> arg0, Pais arg1, Pais arg2) {
                if (arg2 != null) {
                    System.out.println("selecciono pais " + arg2.getId());
                    dataSourceProvincia.clear();
                    dataSourceProvincia.addAll(GestorPais.getInstance().provincias(arg2));
                }
            }
        });

        pais.getSelectionModel().select(0);
        provincia.getSelectionModel().select(0);


        //carga los paices provincias y localidades de las zonas
        this.paisesZona.setItems(dataSourcePais);
        paisesZona.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Pais>() {
            @Override
            public void changed(ObservableValue<? extends Pais> arg0, Pais arg1, Pais arg2) {
                if (arg2 != null) {
                    System.out.println("selecciono pais " + arg2.getId());
                    provinciaZona.getItems().clear();
                    provinciaZona.getItems().addAll(GestorPais.getInstance().provincias(arg2));

                }
            }
        });


        this.provinciaZona.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Provincia>() {
            @Override
            public void changed(ObservableValue<? extends Provincia> selected, Provincia oldValue, Provincia newValue) {
                if (newValue != null) {
                    localidadesZona.getItems().clear();
                    localidadesZona.getItems().addAll(GestorPais.getInstance().localidades(newValue));

                    //dataSourceProvincia.clear();
                    //dataSourceProvincia.addAll( GestorPais.getInstance().provincias(newValue));
                }
            }
        });

        this.localidadesZona.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        
        this.localidadesZona.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Localidad>() {
            @Override
            public void changed(ObservableValue<? extends Localidad> selected, Localidad oldValue, Localidad newValue) {
                if (newValue != null) {
                   if(localidadesZona.getItems().size()==localidadesZona.getSelectionModel().getSelectedItems().size())
                   {
                       seleccionarTodasLocalidades.setSelected(true);
                   }else{
                       seleccionarTodasLocalidades.setSelected(false);
                   }
                }
            }
        });


    }

  




    private void setTablaCoberturaLocalidades() {
        TablaCoberturaActual.setItems(dataSourceTablaLocalidadCobertura);
        TablaCoberturaActual.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        //Hace un binding entre La columna y las propiedades del usuarioViedw
        this.columLocalidad.setCellValueFactory(
                new PropertyValueFactory<Localidad, String>("nombre"));


        this.columProvincia.setCellValueFactory(new Callback<CellDataFeatures<Localidad, String>, ObservableValue<String>>() {
            public ObservableValue<String> call(CellDataFeatures<Localidad, String> p) {
                // p.getValue() returns the Person instance for a particular TableView row
                return new SimpleStringProperty(p.getValue().getProvincia().getNombre());
            }
        });

        this.columPais.setCellValueFactory(new Callback<CellDataFeatures<Localidad, String>, ObservableValue<String>>() {
            public ObservableValue<String> call(CellDataFeatures<Localidad, String> p) {
                // p.getValue() returns the Person instance for a particular TableView row
                return new SimpleStringProperty(p.getValue().getProvincia().getPais().getNombre());
            }
        });



        /* Localidad l=new Localidad("Recreo",new Provincia("Santa Fe",new Pais("Argentina")));
         dataSourceTablaLocalidadCobertura.add(l);*/

    }

    public void eventAgregarZona() {
        //uso un set para borrar duplicados
        Set<Localidad> selection = new HashSet<Localidad>(localidadesZona.getSelectionModel().getSelectedItems());
        selection.addAll(dataSourceTablaLocalidadCobertura);
        this.dataSourceTablaLocalidadCobertura.clear();
        this.dataSourceTablaLocalidadCobertura.addAll(selection);

    }

    public void eventEliminarZona() {

        this.dataSourceTablaLocalidadCobertura.removeAll(new ArrayList(this.TablaCoberturaActual.getSelectionModel().getSelectedItems()));
        this.TablaCoberturaActual.getSelectionModel().clearSelection();

    }
    
    public void seleccionarALL(){
        if(this.seleccionarTodasLocalidades.isSelected()){
           this.localidadesZona.getSelectionModel().selectAll(); 
        }else{
             this.localidadesZona.getSelectionModel().clearSelection();
        }
    }
    
      @Override
    URL getURLFXML() {
          return pathRecusosFXML.class.getResource("CrearAgenciaExternaFXML.fxml");
    }

    private void agregarEscuchadorAgencia() {
      
        this.nombre.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.cuit.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.email.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.condicionFrenteIVA.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.telFijo1.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.telFijo2.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.telCelular1.focusedProperty().addListener(this.escuchadorFocoAgencia);
            this.telCelular2.focusedProperty().addListener(this.escuchadorFocoAgencia);
    }

    private void agregarEscuchadorDomicilio() {
        this.calle.focusedProperty().addListener(this.escuchadorFocoDomicilio);
            this.departamento.focusedProperty().addListener(this.escuchadorFocoDomicilio);
            this.piso.focusedProperty().addListener(this.escuchadorFocoDomicilio);
            this.numero.focusedProperty().addListener(this.escuchadorFocoDomicilio);
            this.localidad.getTextField().focusedProperty().addListener(this.escuchadorFocoDomicilio);
    }
    
     private ImageView crearImagenSuccess() {
        Image image = new Image(pathRecusosIMG.class.getResourceAsStream("success.png"));
        
        return new ImageView(image);
    }

    private ImageView crearImagenError() {
        Image image = new Image(pathRecusosIMG.class.getResourceAsStream("error.png"));
        return new ImageView(image);
    }
     
}
